package com.linwoain.wififileserver;

import android.Manifest;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.koushikdutta.async.ByteBufferList;
import com.koushikdutta.async.DataEmitter;
import com.koushikdutta.async.callback.CompletedCallback;
import com.koushikdutta.async.callback.DataCallback;
import com.koushikdutta.async.http.body.MultipartFormDataBody;
import com.koushikdutta.async.http.body.Part;
import com.koushikdutta.async.http.server.AsyncHttpServer;
import com.koushikdutta.async.http.server.AsyncHttpServerRequest;
import com.koushikdutta.async.http.server.AsyncHttpServerResponse;
import com.koushikdutta.async.http.server.HttpServerRequestCallback;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.OnNeverAskAgain;
import permissions.dispatcher.OnPermissionDenied;
import permissions.dispatcher.RuntimePermissions;

@RuntimePermissions public class SecondActivity extends AppCompatActivity {

  private static final String TAG = "wifi_log";
  AsyncHttpServer server = new AsyncHttpServer();

  public static String convertStreamToString(InputStream is) {
        /*
          * To convert the InputStream to String we use the BufferedReader.readLine()
          * method. We iterate until the BufferedReader return null which means
          * there's no more data to read. Each line will appended to a StringBuilder
          * and returned as String.
          */
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();

    String line = null;
    try {
      while ((line = reader.readLine()) != null) {
        sb.append(line).append("\n");
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      try {
        is.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    return sb.toString();
  }

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);
    SecondActivityPermissionsDispatcher.startServiceWithCheck(this);
  }

  @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
      @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    SecondActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
  }

  @NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) void startService() {

    server.post("/upload", new HttpServerRequestCallback() {
      @Override public void onRequest(AsyncHttpServerRequest request,
          final AsyncHttpServerResponse response) {
        final MultipartFormDataBody body = (MultipartFormDataBody) request.getBody();
        Log.i(TAG, "onRequest: 接收到上传请求");

        body.setEndCallback(new CompletedCallback() {
          @Override public void onCompleted(Exception ex) {
            if (ex == null) {
              response.code(200).end();
            } else {
              response.code(505).end();
            }
          }
        });

        body.setEndCallback(new CompletedCallback() {
          @Override public void onCompleted(Exception ex) {

          }
        });

        body.setMultipartCallback(new MultipartFormDataBody.MultipartCallback() {
          @Override public void onPart(final Part part) {
            if (part.isFile()) {
              Log.d(TAG, "onPart: 收到一个文件，" + part.getFilename());

              try {
                final FileOutputStream outputStream = new FileOutputStream(
                    new File(Environment.getExternalStorageDirectory().getAbsolutePath(),
                        part.getFilename()));
                body.setDataCallback(new DataCallback() {
                  @Override public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) {
                    Log.d(TAG, "onDataAvailable: 开始接收");
                    try {
                      outputStream.write(bb.getAllByteArray());
                      outputStream.flush();
                    } catch (IOException e) {
                      e.printStackTrace();
                    }

                    bb.recycle();
                  }
                });
              } catch (FileNotFoundException e) {
                e.printStackTrace();
              }

            } else {
              Log.e(TAG, "onPart: 不是文件");
            }
          }
        });
      }
    });

    server.get("/", new HttpServerRequestCallback() {
      @Override
      public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
        String path = request.getQuery().getString("path");
        String rootPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        String realPath = TextUtils.isEmpty(path) ? rootPath : path;
        File file = new File(realPath);
        if (file.isFile()) {
          response.sendFile(file);
        } else {
          StringBuilder builder = new StringBuilder();
          if (!realPath.equals(rootPath)) {
            builder.append("<p><a href='/?path=")
                .append(realPath.substring(0, realPath.lastIndexOf("/")))
                .append("'>返回上级菜单</a></p>");
          }
          File[] files = file.listFiles();
          for (File child : files) {
            builder.append("<p><a href='/?path=")
                .append(child.getAbsolutePath())
                .append("'>")
                .append(child.getName())
                .append("</a></p>");
          }
          try {
            response.send(convertStreamToString(getAssets().open("file.html")).replace("#content",
                builder.toString()));
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
    });

    server.listen(5001);
    String text = String.format("http://%s:5001", getIp());
    Log.i(TAG, "startService: " + text);
    ((TextView) findViewById(R.id.tv_ip)).setText(text);
  }

  @OnPermissionDenied(Manifest.permission.WRITE_EXTERNAL_STORAGE) void onStorageDenied() {
    toast("权限请求被拒绝");
  }

  private void toast(String s) {
    Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
  }

  @OnNeverAskAgain(Manifest.permission.WRITE_EXTERNAL_STORAGE) void onStorageNeverAskAgain() {
    toast("请在设置中打开读写外置存储权限");
  }

  private String getIp() {
    WifiManager wifiManager =
        (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    //判断wifi是否开启
    if (!wifiManager.isWifiEnabled()) {
      wifiManager.setWifiEnabled(true);
    }
    WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    int ipAddress = wifiInfo.getIpAddress();
    return (ipAddress & 0xFF)
        + "."
        + ((ipAddress >> 8) & 0xFF)
        + "."
        + ((ipAddress >> 16) & 0xFF)
        + "."
        + (ipAddress >> 24 & 0xFF);
  }
}
